package org.example.erat.controller;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.erat.dto.ResponseDTO;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 文件系统控制器
 * 处理文件系统相关操作，如选择目录、扫描目录、重命名文件等
 */
@RestController
@RequestMapping("/api/reports")
@RequiredArgsConstructor
@Slf4j
public class FileSystemController {

    /**
     * 获取默认目录列表
     * 返回系统中的默认目录列表，供用户选择
     * @return 响应，包含默认目录列表
     */
    @GetMapping("/default-directories")
    public ResponseDTO<List<Map<String, String>>> getDefaultDirectories() {
        log.info("获取默认目录列表请求");

        List<Map<String, String>> directories = new ArrayList<>();

        // 添加系统默认目录
        String userHome = System.getProperty("user.home");
        addDirectoryIfExists(directories, "用户目录", userHome);
        addDirectoryIfExists(directories, "桌面", userHome + "/Desktop");
        addDirectoryIfExists(directories, "文档", userHome + "/Documents");
        addDirectoryIfExists(directories, "下载", userHome + "/Downloads");

        // Windows 特定目录
        if (System.getProperty("os.name").toLowerCase().contains("win")) {
            for (File file : File.listRoots()) {
                String path = file.getAbsolutePath();
                addDirectoryIfExists(directories, path, path);
            }

            // 添加常用文件夹
            addDirectoryIfExists(directories, "C盘", "C:\\");
            addDirectoryIfExists(directories, "D盘", "D:\\");
            addDirectoryIfExists(directories, "程序文件", "C:\\Program Files");
        }

        // Linux/Mac 特定目录
        else {
            addDirectoryIfExists(directories, "根目录", "/");
            addDirectoryIfExists(directories, "用户目录", "/home");
            addDirectoryIfExists(directories, "临时目录", "/tmp");
        }

        return ResponseDTO.success("获取默认目录列表成功", directories);
    }

    /**
     * 获取目录内容
     * 返回指定目录中的子目录和文件
     * @param path 目录路径
     * @return 响应，包含目录内容
     */
    @GetMapping("/directory-content")
    public ResponseDTO<Map<String, Object>> getDirectoryContent(@RequestParam String path) {
        log.info("获取目录内容请求: {}", path);

        if (path == null || path.isEmpty()) {
            return ResponseDTO.error(400, "目录路径不能为空");
        }

        File directory = new File(path);
        if (!directory.exists() || !directory.isDirectory()) {
            return ResponseDTO.error(400, "目录不存在或不是目录");
        }

        Map<String, Object> result = new HashMap<>();
        List<Map<String, String>> directories = new ArrayList<>();
        List<Map<String, String>> files = new ArrayList<>();

        File[] fileList = directory.listFiles();
        if (fileList != null) {
            for (File file : fileList) {
                Map<String, String> fileInfo = new HashMap<>();
                fileInfo.put("name", file.getName());
                fileInfo.put("path", file.getAbsolutePath());
                fileInfo.put("lastModified", String.valueOf(file.lastModified()));

                if (file.isDirectory()) {
                    directories.add(fileInfo);
                } else {
                    files.add(fileInfo);
                }
            }
        }

        result.put("directories", directories);
        result.put("files", files);
        result.put("currentPath", path);

        return ResponseDTO.success("获取目录内容成功", result);
    }

    /**
     * 选择目录
     * 由于无法在服务器端打开文件选择对话框，这个方法现在只接受客户端传来的路径
     * @param requestBody 请求体，包含目录路径
     * @return 响应，包含选择的目录路径
     */
    @PostMapping("/select-directory")
    public ResponseDTO<Map<String, String>> selectDirectory(@RequestBody Map<String, String> requestBody) {
        String path = requestBody.get("path");
        log.info("选择目录请求: {}", path);

        if (path == null || path.isEmpty()) {
            return ResponseDTO.error(400, "目录路径不能为空");
        }

        File directory = new File(path);
        if (!directory.exists() || !directory.isDirectory()) {
            return ResponseDTO.error(400, "目录不存在或不是目录");
        }

        Map<String, String> data = new HashMap<>();
        data.put("path", path);

        return ResponseDTO.success("目录选择成功", data);
    }

    /**
     * 添加目录到列表中（如果目录存在）
     * @param directories 目录列表
     * @param name 目录名称
     * @param path 目录路径
     */
    private void addDirectoryIfExists(List<Map<String, String>> directories, String name, String path) {
        File directory = new File(path);
        if (directory.exists() && directory.isDirectory()) {
            Map<String, String> directoryInfo = new HashMap<>();
            directoryInfo.put("name", name);
            directoryInfo.put("path", path);
            directories.add(directoryInfo);
        }
    }

    /**
     * 扫描目录
     * 扫描指定目录，返回目录中的文件信息
     * @param requestBody 请求体，包含目录路径
     * @return 响应，包含扫描结果
     */
    @PostMapping("/scan-directory")
    public ResponseDTO<Map<String, Object>> scanDirectory(@RequestBody Map<String, String> requestBody) {
        String directoryPath = requestBody.get("directoryPath");
        log.info("扫描目录请求: {}", directoryPath);

        if (directoryPath == null || directoryPath.isEmpty()) {
            return ResponseDTO.error(400, "目录路径不能为空");
        }

        File directory = new File(directoryPath);
        if (!directory.exists() || !directory.isDirectory()) {
            return ResponseDTO.error(400, "目录不存在或不是目录");
        }

        try {
            // 扫描目录
            Map<String, Object> result = scanDirectoryFiles(directory);
            return ResponseDTO.success("目录扫描成功", result);
        } catch (Exception e) {
            log.error("扫描目录失败", e);
            return ResponseDTO.error(500, "扫描目录失败: " + e.getMessage());
        }
    }

    /**
     * 重命名文件
     * @param requestBody 请求体，包含旧文件路径和新文件名
     * @return 响应，包含重命名结果
     */
    @PostMapping("/rename-file")
    public ResponseDTO<Map<String, String>> renameFile(@RequestBody Map<String, String> requestBody) {
        String oldPath = requestBody.get("oldPath");
        String newName = requestBody.get("newName");
        log.info("重命名文件请求: oldPath={}, newName={}", oldPath, newName);

        if (oldPath == null || oldPath.isEmpty() || newName == null || newName.isEmpty()) {
            return ResponseDTO.error(400, "旧文件路径和新文件名不能为空");
        }

        File oldFile = new File(oldPath);
        if (!oldFile.exists() || !oldFile.isFile()) {
            return ResponseDTO.error(400, "文件不存在或不是文件");
        }

        try {
            // 获取父目录
            String parentPath = oldFile.getParent();
            File newFile = new File(parentPath, newName);

            // 重命名文件
            boolean success = oldFile.renameTo(newFile);
            if (success) {
                Map<String, String> data = new HashMap<>();
                data.put("oldPath", oldPath);
                data.put("newPath", newFile.getAbsolutePath());
                data.put("newName", newName);

                return ResponseDTO.success("文件重命名成功", data);
            } else {
                return ResponseDTO.error(500, "文件重命名失败");
            }
        } catch (Exception e) {
            log.error("重命名文件失败", e);
            return ResponseDTO.error(500, "重命名文件失败: " + e.getMessage());
        }
    }

    /**
     * 扫描目录文件
     * @param directory 目录
     * @return 扫描结果
     */
    private Map<String, Object> scanDirectoryFiles(File directory) throws IOException {
        Map<String, Object> result = new HashMap<>();

        // 获取目录中的所有文件
        File[] files = directory.listFiles();
        if (files == null) {
            result.put("files", new File[0]);

            Map<String, Object> exceptions = new HashMap<>();
            exceptions.put("invalidFormat", new File[0]);
            exceptions.put("unknownStudent", new File[0]);
            result.put("exceptions", exceptions);

            return result;
        }

        // 模拟异常文件
        Map<String, Object> exceptions = new HashMap<>();
        exceptions.put("invalidFormat", new File[0]);
        exceptions.put("unknownStudent", new File[0]);

        result.put("files", files);
        result.put("exceptions", exceptions);

        return result;
    }
}
